using System;
using System.Collections.Generic;
using System.Text;
using DCI6;
using DCI6.Client.API;

namespace DCIAPIRMSampleCode {
    internal class QuerySampleCode {
        public QueryCommand CreateQueryCommand(Advertisement advertisement) {
            /**
             * Creating and executing query is very similar to creating subscription.
             * User has an option to input 3 parameters parameters: 
             * 1.Meta data filter that corresponds to
             * subscribe/metadataFilter/xpath field in dds.xsd . Meta data filter can contain a number
             * of different conditions that can be joined together and converted into xpath statement
             * by DCI
             * 2. Distribution type that corresponds to subscribe/policy/rule field in dds.xsd. Setting
             * this field will determine whether query is GLOBAL or LOCAL to that particular DDS node.
             * 3. Compression type that corresponds to subscribe/policy/controlPolicy field in dds.xsd.
             * The appropriate values for this field as per dds.xsd are: NONE
             * GZIP
             * FI
             * GFI
             * 
             * Additionally, user must provide an AreaOfInterest that corresponds to subscribe/areaOfInterest
             * field in dds.xsd
             * 		 
             */

            /**
             * Creating Area of Interest
             */
            AreaOfInterest aoi = AreaOfInterest.GLOBAL;

            /**
             * Creating a holder object that will contain conditions for meta data filtering.
             */
            List<Criterion> metadata = new List<Criterion>();

            /**
             * Populating with different subscription criteria 
             */
            metadata.Add(Query.HasCategory("POS-RPT"));
            metadata.Add(Query.HasKeyword("MCS"));
            metadata.Add(Query.DescriptionEquals("PASS:"));
            metadata.Add(Query.HasClassification(Classification.UNCLASSIFIED));
            metadata.Add(Query.OrganizationEquals("Army"));
            metadata.Add(Query.TopicTitleEquals("POS-RPT:MCS:US/ARMY/4ID"));

            /**
             * Constructing a meta data query object from the list of entered criteria
             */
            Query metadataQuery = new Query(Query.And(metadata.ToArray()));


            /**
             * Setting distribution field on the query object
             */
            metadataQuery.Distribution = Advertisement.Distribution.LOCAL;

            /**
             * Setting Compression field on the query object
             */
            metadataQuery.Compression = CompressionType.NONE;


            /**
             * Constructing Content Filtering
             */

            List<Criterion> content = new List<Criterion>();

            /**
             * Populating with different subscription criteria 
             */
            content.Add(Query.LacksCategory("ENEMY-SIT"));


            /**
             * Constructing a meta data query object from the list of entered criteria
             */
            Query contentQuery = new Query(Query.And(content.ToArray()));


            QueryCommand queryCommand = new QueryCommand(metadataQuery, contentQuery, aoi, Period.EARLIEST);

            return queryCommand;
        }

        public QueryCommand CreateSimpleQueryCommandForAdv(Advertisement advertisement) {
            List<Criterion> metadata = new List<Criterion>();
            metadata.Add(Query.HasCategory(advertisement.Categories[0]));
            metadata.Add(Query.LacksCategory("DummyCategory"));
            Query q = new Query(Query.And(metadata.ToArray()));
            QueryCommand qc = new QueryCommand(q, AreaOfInterest.GLOBAL, Period.EARLIEST);
            return qc;
        }

        public void ExecuteLocalSyncronousQuery(QueryCommand querycommand, String ddsConfigConnectionID) {
            /**
             * ExecuteLocalSynchronousQuery call make a synchronized request 
             * through the DCI Service to DDS and thus is not recommend for large data 
             * sets. Also this call forces a Local Distribution Rule and will
             * only return Items from a local DDS.
             */
            Console.WriteLine("Sending QueryCommand ExecuteLocalSynchronousQuery Request...");
            List<Item> items = querycommand.ExecuteLocalSynchronousQuery(ddsConfigConnectionID);
            Console.WriteLine("ExecuteLocalSynchronousQuery returned [{0}] items:", items.Count);
            foreach (Item i in items) {
                Console.WriteLine("Item ID: [{0}]", i.ItemID);
            }
        }

        public void ExecuteQuery(QueryCommand querycommand, String ddsConfigConnectionID) {
            /**
             * Execute call will return items asychronously through
             * the same call back handlers that subscriptions use 
             * (validPublicationReceived and invalidPublicationReceived).
             * Use the DCIItemMetaData isValidQueryID method in your 
             * callback handler to determine if the item is being returned
             * from a Query Request.
             */
            Console.WriteLine("Sending QueryCommand Execute Request...");
            querycommand.Execute(ddsConfigConnectionID);
            Console.WriteLine("Execute Query Called");
        }

        public String ExecuteAdvanceQuery(QueryCommand querycommand, String ddsConfigConnectionID) {
            /**
             * ExecuteAdvanceQuery call will return items asychronously through
             * the validQueryPublicationReceived and invalidQueryPublicationReceived
             * callback handlers. Use this call if it is important for you to distinguish
             * query data from subscription data or multiple query calls. You can use
             * the queryID string returned from this call to map returned items to
             * the correct queries.
             */
            Console.WriteLine("Sending QueryCommand ExecuteAdvanceQuery Request...");
            String queryID = querycommand.ExecuteAdvanceQuery(ddsConfigConnectionID);
            Console.WriteLine("ExecuteAdvanceQuery returned a Query ID [{0}] ", queryID);
            return queryID;
        }
    }
}